<?php


namespace App\Http\Controllers;


use App\Http\Service\CountryService;
use App\Http\Service\DeviceService;
use App\Http\Util\Wechat;
use App\Jobs\CancelWarning;
use App\Jobs\CheckWarning;
use App\Model\Agent;
use App\Model\AreasCn;
use App\Model\Business;
use App\Model\BusinessConf;
use App\Model\Contract;
use App\Model\Device;
use App\Model\DevicePowerLog;
use App\Model\DevicePowerLog1;
use App\Model\DeviceWarning;
use App\Model\House;
use App\Service\Baofu;
use App\Service\BaofuPay;
use App\User;
use App\Utils\Result;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;

class DeviceController
{
    public function create(Request $request)
    {
        Log::notice('device create', $request->all());
        $token = $request->header('token');

        if (!$token or $token != 'CC20231001JH001') {
            return Result::error(403, 'token错误');
        }

        $mac = $request->input('mac');
        $sn = $request->input('sn');
        $name = $request->input('name');
        $overload = $request->input('overload') ?? '';

        if (!$mac or !$sn or !$name) {
            return Result::error(401, '参数错误');
        }
        $mac = str_replace(":", "", $mac);

        $agentMobile = $request->input('agentMobile');

        $deviceModel = Device::query()->where('mac', $request->input('mac'))
            ->orWhere('sn', $sn)->first();
        if ($deviceModel && $deviceModel->mac == $mac) {
            return Result::error(401, 'MAC地址已存在');
        }
        if ($deviceModel && $deviceModel->sn == $sn) {
            return Result::error(401, '二维码编号已存在');
        }

        $agent = $this->updateAgent($agentMobile);

        $deviceModel = new Device();
        $deviceModel->mac = $mac;
        $deviceModel->name = $name;
        $deviceModel->sn = $sn;
        $deviceModel->type = 1;
        $deviceModel->pay_mode = $request->input('pay_mode') == 2 ? 2 : 1;
        $deviceModel->net_type = $request->input('netType') == 1 ? 1 : 2;
        if ($deviceModel->net_type == 1) {
            $deviceModel->is_master = 1;
        }
        if ($agent) {
            $deviceModel->agent_id = $agent->id;
        }
        $deviceModel->overload = $overload;
        $deviceModel->save();

        return Result::success($deviceModel);
    }

    protected function updateAgent($mobile)
    {
        if (!$mobile) {
            return null;
        }
        $agent = Agent::query()->where('mobile', $mobile)->first();
        if (!$agent) {
            $agent = new Agent();
            $agent->mobile = $mobile;
            $agent->name = '';
            $agent->password = '';
            $agent->token = '';
            $agent->save();
        }
        return $agent;
    }


    public function pushWarning(Request $request){
        $openid = $request->input('openid');
        $token = Wechat::getAccessToken();
        $postData = [
            'touser' => $openid,
            'template_id' => 'DYeA1Z_M4GNeh1uG3VDo1YRablzbg_IUJ0snQeFPdM0',
            'data' => [
                'thing8' => ['value' =>  'test messss'],
                'thing9' => ['value' => '电表'],
                'thing10' => ['value' => '0度'],
                'time41' => ['value' =>date('Y年m月d日')],
                'thing4' => ['value' => '您的剩余电量已不足请及时处理']
            ]
        ];
        $postData =json_encode($postData);
        $result =  Wechat::sendMessage($postData,$token);
        $result  = json_decode($result,true);
        return Result::success($result);
    }

    public function tjTest()
    {
        $cacheKey = 'LOCK_FOREACH';
        if (Redis::exists($cacheKey)) {
            return Result::error(1001, ' the last not success');
        }
        Redis::set($cacheKey, 1);
        $list = DevicePowerLog1::query()
            ->where('is_sen', 1)
            ->where('created_at', '>=', '2024-04-01:00:00:00')
            ->where('created_at', '<', '2024-08-01:00:00:00')
            ->orderBy('id','desc')
            ->limit(500)
            ->get();
        foreach ($list as $k => &$v) {
            if ($v->xh >= $v->total && $v->xh > 1000) {
                $v->is_sen += 1;
                $v->save();
                break;
            }
            $time = strtotime($v->created_at);
            $hourKey = $v->device_id . '-' . date('YmdH', $time);
            $dayKey = $v->device_id . '-' . date('Ymd', $time);
            $monthKey = $v->device_id . '-' . date('Ym', $time);
            if (Redis::exists($hourKey)) {
                if ($v->xh > 0) {
                    Redis::incrBy($hourKey, $v->xh);
                }
            } else {
                if ($v->xh > 0) {
                    Redis::setex($hourKey, 3600 * 24 * 730, $v->xh);
                }
            }
            if (Redis::exists($dayKey)) {
                if ($v->xh > 0) {
                    Redis::incrBy($dayKey, $v->xh);
                }
            } else {
                if ($v->xh > 0) {
                    Redis::setex($dayKey, 3600 * 24 * 730, $v->xh);
                }
            }
            if (Redis::exists($monthKey)) {
                if ($v->xh > 0) {
                    Redis::incrBy($monthKey, $v->xh);
                }
            } else {
                if ($v->xh > 0) {
                    Redis::setex($monthKey, 3600 * 24 * 730, $v->xh);
                }
            }
            $v->is_sen += 1;
            $v->save();
        }
        Redis::del($cacheKey);
        return Result::success();
    }

    public function delTest(Request $request)
    {
        $device = Device::get();
        $date = $request->input('date');
        $month = $request->input('month');
        foreach ($device as $v) {
           $key1 = $v->id . '-' . $date;
            if (Redis::exists($v->id . '-' . $month)) {
                Redis::del($v->id . '-' . $month);
            }
            if(Redis::exists($key1)){
                Redis::del($key1);
            }
            for ($j = 0; $j < 24; $j++) {
                if ($j < 10) {
                    $k1 = '0' . $j;
                } else {
                    $k1 = $j;
                }
                $key3 = $v->id . '-' . $date . $k1;
                if(Redis::exists($key3)){
                    Redis::del($key3);
                }
            }
        }

        return Result::success();

    }


    /**附近房源列表
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function areaList(Request $request)
    {
        $lat = $request->input('lat');
        $lng = $request->input('lng');
        $radius = $request->input('radius');
        $list = DB::table('house')
            ->select('province', 'city', 'district',
                'estate_name', 'name', 'country', 'lat', 'lng', 'id',
                DB::raw("ST_Distance_Sphere(point(lng, lat), point({$lng}, {$lat})) AS distance"))
            ->whereRaw("ST_Distance_Sphere(point(lng, lat), point({$lng}, {$lat})) < ?", [$radius])
            ->orderBy('distance', 'asc') // 按距离升序排序
            ->get();
        $list = json_encode($list);
        $list = json_decode($list, true);
        foreach ($list as &$v) {
            $v['distance'] = number_format($v['distance'], 2, '.', '');
        }
        return Result::success($list);
    }

    /**设备移动接口
     * @param Request $request
     * @return void
     */
    public function deviceDetail(Request $request)
    {
        $sn = $request->input('sn');
        $houseId = $request->input('house_id');
        if (!$sn && !$houseId) {
            return Result::error(1001, '缺少参数设备编号或房源信息');
        }
        try{
            if ($houseId) {
                $data = Device::query()->where('house_id', $houseId)
                    ->with('house')
                    ->first(['id', 'sn', 'business_id', 'price', 'online_status', 'house_id', 'mobile', 'du', 'total', 'net_type', 'is_master', 'signal']);
                if(!$data){
                    return Result::error(1003,'房源暂无设备信息');
                }
                if ($data && $data->business_id) {
                    $userId = Business::query()->where('id', $data->business_id)->value('user_id');
                    $data->business_mobile = User::query()->where('id', $userId)->value('mobile');
                }
            } else {
                $data = Device::query()->where('sn', $sn)
                    ->with('house')
                    ->first(['id', 'sn', 'business_id', 'house_id', 'online_status', 'mobile', 'du', 'price', 'total', 'net_type', 'is_master', 'signal']);
                if(!$data){
                    return Result::error(1002,'设备编号不存在');
                }
                if ($data->business_id) {
                    $userId = Business::query()->where('id', $data->business_id)->value('user_id');
                    $data->business_mobile = User::query()->where('id', $userId)->value('mobile');
                }
            }
            $data->residue_money = $data->du * $data->price;
            return Result::success($data);
        }catch (\Exception $e){
            return Result::error(1001,$e->getMessage());
        }
    }

    /**根据房源获取手机号
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function getDeviceList(Request $request)
    {
        $houseId = $request->input('house_id');
        if (!$houseId) {
            return Result::error(1001, '缺少房间id');
        }
        $data = Device::query()->where('house_id', $houseId)
//            ->with('house')
            ->get(['id', 'sn', 'online_status', 'house_id', 'du', 'total', 'net_type', 'is_master', 'signal']);
        return Result::success($data);
    }


    /**电量折线图
     * @param Request $request
     * @return void
     */
    public function powerChart(Request $request)
    {
        $sn = trim($request->input('sn'));
        $type = trim($request->input('type'));
        $time = $request->input('time');
        $deviceId = Device::query()->where('sn', $sn)
            ->value('id');
        if (!$deviceId) {
            return Result::error(1001, '设备编号不存在');
        }
        $startYear = 2023;
        $nowYear = date('Y');
        $data['all'] = 0;
        try {
            for ($l = $startYear; $l <= $nowYear; $l++) {
                for ($m = 1; $m < 13; $m++) {
                    if ($m == 12) {
                        $startAll = $l . '-' . $m;
                    } else {
                        if ($m < 10) {
                            $m = '0' . $m;
                        }
                        $startAll = $l . '-' . $m;
                    }
                    $cacheKey1 = str_replace('-', "", $startAll);
                    $cacheKey = str_replace(' ', "", $cacheKey1);
                    $key = $deviceId . '-' . $cacheKey;

                    if (Redis::exists($key)) {
                        $tempPower = Redis::get($key);
                        if ($tempPower) {
                            $data['all'] += $tempPower;
                        }
                    }
                }
            }
            if ($type == 'day') {
                if ($time) {
                    $now = new \DateTime($time);
                } else {
                    $now = new \DateTime();
                }
                $startOfDay = clone $now;
                $startOfDay->setTime(0, 0, 0);
                $now->setTime(23, 59, 59);
                $i = 0;
                $data['now_total'] = 0;
                while ($startOfDay <= $now) {
                    if ($i > 24) {
                        break;
                    }
                    // 将当前小时的时间添加到数组中
                    $tempArr = [];
                    $data['keys'][] = $tempArr['start'] = $startOfDay->format('Y-m-d H');
                    // 移动到下一个小时
                    $tempArr['end'] = $startOfDay->modify('+1 hour');
                    $tempArr['end'] = $tempArr['end']->format('Y-m-d H');
                    $cacheKey1 = str_replace('-', "", $tempArr['start']);
                    $cacheKey = str_replace(' ', "", $cacheKey1);
                    $key = $deviceId . '-' . $cacheKey;
                    if (Redis::exists($key)) {
                        $tempArr['power'] = Redis::get($key);
                        $tempArr['power'] = $tempArr['power'] / 1000;
                        $data['data'][] = $tempArr['power'] = number_format($tempArr['power'], 2, '.', '');
                        $data['table'][] = $tempArr;
                    } else {
                        $tempArr['power'] = 0;
                        $data['data'][] = 0;
                    }
                    $data['now_total'] += (float)$tempArr['power'];
                    $i++;
                }
            } elseif ($type == 'month') {
                if ($time) {
                    $dateStart = new \DateTime($time . "-01");
                } else {
                    $dateStart = new \DateTime(date('Y-m') . "-01");
                }
                $dateEnd = (clone $dateStart)->modify('first day of next month');
                $i = 0;
                $data['now_total'] = 0;
                while ($dateStart < $dateEnd) {
                    if ($i > 31) {
                        break;
                    }
                    $tempArr = [];
                    $data['keys'][] = $tempArr['start'] = $dateStart->format('Y-m-d');
                    $tempArr['end'] = $dateStart->modify('+1 day');
                    $tempArr['end'] = $tempArr['end']->format('Y-m-d');
                    $cacheKey1 = str_replace('-', "", $tempArr['start']);
                    $cacheKey = str_replace(' ', "", $cacheKey1);
                    $key = $deviceId . '-' . $cacheKey;
                    if (Redis::exists($key)) {
                        $tempArr['power'] = Redis::get($key);
                        $tempArr['power'] = $tempArr['power'] / 1000;
                        $data['data'][] = $tempArr['power'] = number_format($tempArr['power'], 2, '.', '');
                        $data['table'][] = $tempArr;
                    } else {
                        $tempArr['power'] = 0;
                        $data['data'][] = 0;
                    }
                    $data['now_total'] += (float)$tempArr['power'];
                    $i++;
                }
            } else {
                if ($time) {
                    $year = $time;
                } else {
                    $year = date('Y');
                }
                $data['now_total'] = 0;
                for ($month = 1; $month <= 12; $month++) {
                    // 使用 str_pad() 确保月份有两位数字
                    $formattedMonth = str_pad($month, 2, '0', STR_PAD_LEFT);
                    $tempArr = [];
                    $data['keys'][] = "$year-$formattedMonth";

                    if ($month == 12) {
                        $tempArr['start'] = $year . '-' . $month;
                        $tempArr['end'] = $year . '-' . $month;
                    } else {
                        if ($month < 10) {
                            $month = '0' . $month;
                        }
                        $tempArr['start'] = $year . '-' . $month;
                        $tempArr['end'] = $year . '-' . ($month + 1);
                    }
                    $cacheKey1 = str_replace('-', "", $tempArr['start']);
                    $cacheKey = str_replace(' ', "", $cacheKey1);
                    $key = $deviceId . '-' . $cacheKey;
                    if (Redis::exists($key)) {
                        $tempArr['power'] = Redis::get($key);
                        $tempArr['power'] = $tempArr['power'] / 1000;
                        $data['data'][] = $tempArr['power'] = number_format($tempArr['power'], 2, '.', '');
                        $data['table'][] = $tempArr;
                    } else {
                        $data['data'][] = 0;
                        $tempArr['power'] = 0;
                    }

                    $data['now_total'] += (float)$tempArr['power'];
                }
            }
            $data['now_total'] = number_format((float)$data['now_total'], 2, '.', '');
            if ($data['all'] > 0) {
                $data['all'] = number_format($data['all'] / 1000, 2, '.', '');
            }

            return Result::success($data);
        } catch (\Exception $e) {
            return Result::error(400, '操作繁忙，请稍后重试');
        }
    }


    /**
     * 告警
     */
    public function setWarning(Request $request)
    {
        $list = Device::query()
            ->where('net_type',1)
            ->where('house_id', '>', 0)
            ->where('mobile','>',0)
            ->get(['id']);
        foreach ($list as $k => $v) {
            dispatch(new CheckWarning($v->id))->delay($k);
        }
        return Result::success($list);
    }

    public function testWarning(Request $request){
        $push['regionCode'] = 330723103255;
        $push['sn'] = 'YM2044685';
        $push['warningDate'] = date('Y-m-d');
        $push['startDate'] = '2025-01-03';
        $push['endDate'] = '2025-01-05';
        $push['consume'] = 3;
        $push['phone'] = 18868546734;
        $push['name'] = 'wind';
        $push['address'] = '浙江省金华市武义县茆阁村';
        $push['room'] = '1004房间';
        $countryService = new CountryService();
        $countryService->pushWarning($push);
    }

    public function cancelWarning(Request $request){
        $list = Device::query()
            ->where('net_type',1)
            ->where('house_id', '>', 0)
            ->where('is_warning',1)
            ->get(['id']);
        foreach ($list as $v) {
            dispatch(new CancelWarning($v->id));
        }
        return Result::success($list);
    }


    public function testCountry(Request $request){
        $service = new CountryService();
        $limit = $request->input('limit',1);
        $service->autoPush1($limit);
    }

    public function getBusinessConf(Request $request){
        $sn = $request->input('sn');
        $businessId = Device::query()->where('sn',$sn)->value('business_id');
        if (!$businessId) {
            return Result::error(1001,'房东信息不存在');
        }
        $businessConf = BusinessConf::query()->where('business_id',$businessId)
            ->first(['show_basic_price','show_service_price']);
        return Result::success($businessConf);
    }


    public function deleteLog(Request $request){
        // 获取当前日期1个月前的日期
        $limit = $request->input('limit',5000);
        $halfMonthAgo = Carbon::now()->subDays(15);
        $formattedDate = $halfMonthAgo->format('Y-m-d');
        DevicePowerLog::query()->where('created_at','<', $formattedDate)
            ->limit($limit)
            ->orderBy('id','asc')
            ->delete();
    }


    public function changePrice(Request $request){
        $agents = Business::query()->where('agent_id',22)->pluck('id')->toArray();
        Device::query()->whereIn('business_id',$agents)->update(['agent_id'=>22]);
    }

    public function deleteHouse(Request $request){
        $list = House::query()
            ->whereNull('tag')
            ->limit(1000)
            ->orderBy('id','asc')
            ->get();
        foreach($list as &$v){
            $v->tag = 1;
            $v->save();
            $check = Device::query()->where('house_id',$v->id)->count();
            $check1 = Contract::query()->where('house_id',$v->id)->count();
            if($check <= 0 && $check1 <= 0){
                echo '['.$v->id.']';
                $v->delete();
            }
        }
    }


    public function testWhite(Request $request){
        if(Redis::exists('sub_warning_15044')){
            echo 1;
        }else{
            echo 2;
        }
        return ;
        $token = Wechat::getAccessToken();
//        $postData =[
//            'touser' => 'oYmeY5QT89Q_qg4AATeRdEmWsDMo',
//            'template_id'=>'DYeA1Z_M4GNeh1uG3VDo1YRablzbg_IUJ0snQeFPdM0',
//            'data' =>[
//                'thing4'=>['value'=>'测试数据1'],
//                'thing8'=>['value'=>'测试数据1'],
//                'thing9'=>['value'=>'测试数据1'],
//                'thing10'=>['value'=>'测试数据1'],
//                'time41' => ['value'=>date('Y-m-d',time())]
//            ]
//        ];
        $postData = [
            'touser' => 'oYmeY5ULXHrbU4gokIM8vOgpxShk',
            'template_id' => '6KU5FXZLFqoV3XFZdu0HAF85ZfVYIneU8Nq4N9zMeTM',
            'data' => [
                'amount1' => ['value' => '测试数据1'],
                'thing11' => ['value' => '测试数据1'],
                'character_string13' => ['value' => 'YM420890227514'],
                'character_string6' => ['value' => '4564654efr'],
                'time3' => ['value' => date('Y-m-d H:i:s', time())]
            ]
        ];
        $postData =json_encode($postData);
        Wechat::sendMessage($postData,$token);
    }






    public function exportUsed(Request $request){
        $time = $request->input('time');
        $start = $time[0];
        $end = $time[1];
        $type = $request->input('type',1);
        if (\DateTime::createFromFormat('Y-m-d', $start) && \DateTime::createFromFormat('Y-m-d', $end)) {
            $startDate = new \DateTime($start);
            $endDate = new \DateTime($end);
            $endDate->modify('+1 day'); // 包含结束日期
            $dateRange = [];
            $cacheKey = [];
            $interval = new \DateInterval('P1D'); // 间隔为1天
            $period = new \DatePeriod($startDate, $interval, $endDate);
            foreach ($period as $date) {
                $dateRange[] = $date->format('Y-m-d');
                $cacheKey[] = $date->format('Ymd');
            }
        } else {
            // 处理日期格式错误
            return Result::error(401,'日期格式无效');
        }
        $classId = $request->input('class_id');
        $data = [];
        $houses = House::query()->where('house_class_id',$classId)->get();
        foreach($houses as $house){
            if($type == 2){
                $devices = Device::query()->where('house_id',$house->id)
                    ->where('net_type',1)
                    ->where('type',$type)
                    ->get();
            }else{
                $devices = Device::query()->where('house_id',$house->id)
                    ->where('net_type',1)
                    ->whereIn('type',[1,3,4])
                    ->get();
            }
            $row = [];
            foreach($devices as $device){
                $row[] = $house->name.'['.$device->sn.']';
                foreach($cacheKey as $date){
                    $cacheKey1 = $device->id.'-'.$date;
                    $power = Redis::get($cacheKey1);
                    $power = $power>0?$power/1000:0;
                    if($type == 2){
                        $row[] = $power.'/吨';
                    }else{
                        $row[] = $power.'/kwh';
                    }
                }
                $data[] = $row;
            }
        }
        $spreadsheet = new Spreadsheet();
        $sheet = $spreadsheet->getActiveSheet();
        $lie = [
            'A','B','C','D','E','F',
            'G','H','I','J','K','L',
            'M','N','O','P','Q','R',
            'S','T','U','V','W','X','Y','Z',
            'AA','AB','AC','AD','AE','AF','AG'
        ];
        $sheet->setCellValue('A1', '房间名[设备号]');
        foreach($dateRange as $k => $date1){
            $sheet->setCellValue($lie[$k+1].'1', $date1);
        }

        foreach (range('A', 'AG') as $columnID) {
            $sheet->getColumnDimension($columnID)->setAutoSize(true);
        }

// 设置单元格水平居中的样式数组配置
        $styleArray = [
            'alignment' => [
                'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER,
            ],
        ];

// 应用样式到第一行的A到O列
        $sheet->getStyle('A:AG')->applyFromArray($styleArray);
        $row = 2;
        foreach ($data as $power) {
            foreach($power as $k => $v){
                if($k == 0){
                    $sheet->setCellValue('A' . $row, $v);
                }else{
                    $sheet->setCellValue($lie[$k].$row,$v);
                }
            }
            $row++;
        }
        // 将 Spreadsheet 对象写入 XLSX 文件
        $writer = new Xlsx($spreadsheet);
        // 创建临时文件
        $publicPath =public_path('/upload/xls/');
        $fileName = date('YmdHis', time()) . '-powers.xlsx';
//        $temp_file = tempnam(sys_get_temp_dir(), $fileName);
        $temp_file = $publicPath . $fileName;
        // 保存到临时文件
        $writer->save($temp_file);
        return Result::success(['url' =>'https://ylz.yimitongxun.com/upload/xls/' . $fileName]);
    }


    public function getCacheDraw(Request $request){
        $cacheKey ='DRAW_ORDER'. $request->input('business_id');
        return Redis::get($cacheKey);
    }


    public function getAreas(Request $request){
        $list = AreasCn::get();
        return Result::success($list);
    }



    public function makeFgTest(Request $request){
        $sn = $request->input('sn');
        $device = Device::query()->where('sn',$sn)->first();
        $data = $device->makeFg();
        $service = app()->make(DeviceService::class);
        $result = $service->sendFgb($device->mac,$data);
        return Result::success($result);
    }



    public function test(Request $request){
        $baofu = App::make(Baofu::class); // 通过容器解析依赖
        $result = $baofu->createOrder();
        return $result;
    }


    public function queryAmount(Request $request){
//        $contractNo = $request->input('contractNo');
//        $type = $request->input('type',1);
//        $bfAccount  = app::make(BaofuPay::class);
//        return $bfAccount->queryAmount($contractNo,$type);
// 使用示例
// 在控制器或其他地方使用
        $baofu = new Baofu($request);

// 查询指定时间段的投诉列表
        $result = $baofu->queryComplaintList([
            'beginDate' => '2025-07-01 00:00:00',
            'endDate' => '2025-07-30 23:59:59',
            'limit' => 20,
            'offset' => 1
        ]);

    }


    public function descAmount(Request $request){
        $amount = $request->input('amount');
        $type = $request->input('type');
        $user = User::where('mobile','15305890809')->first();
        $bfAccount  = app::make(BaofuPay::class);
        if($type == 'add'){
            return $bfAccount->subAccount($amount,$user);
        }else{
            return $bfAccount->desAccount($amount,$user);
        }
    }

}
